package com.test.encrypt;


import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


  
/** 
 * 通过AES算法对文本进行加密解密 
 * @author ShaoJiang 
 * 
 */  
public class YLAUtil {  
    private static SecretKey key;                       //加密密钥  
    private static AlgorithmParameterSpec paramSpec;    //算法参数  
    private static Cipher ecipher;                      //加密算法  
    static String charset="UTF-8";
  
    static{       
        try { 
        	String t_key="ceshiMiMa1234567";
        	String t_iv="ceshiJieMa123456";
        	t_key=(t_key==null || "".equals(t_key)) ? "3yrQpIxKCsC49jGi": t_key;
        	t_iv=(t_iv==null || "".equals(t_iv)) ? "ABCHINA..ANIHCBA": t_iv;
        	byte[] keyValue =t_key.getBytes();       //用户密钥  
            byte[] iv =t_iv.getBytes();            //算法参数  
            String mode="AES/CBC/NoPadding";//加解密模式
            
        	key = new SecretKeySpec(keyValue, "AES");
            //使用iv中的字节作为IV来构造一个 算法参数。  
            paramSpec = new IvParameterSpec(iv);  
            //生成一个实现指定转换的 Cipher 对象  
            ecipher = Cipher.getInstance(mode);         
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        } catch (NoSuchPaddingException e) {  
            e.printStackTrace();  
        }catch(Exception e){
        	e.printStackTrace();
        }
    }  
  

    /** 
     * 加密，使用指定数据源生成密钥，使用用户数据作为算法参数进行AES加密 
     * @param msg 加密的数据 
     * @return 
     */  
    public static String encrypt(String msg) {  
        String str = "";  
        try {             
            //用密钥和一组算法参数初始化此 cipher  
            ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);  
            System.out.println("encrypt con :"+msg);
            System.out.println("encrypt length:"+msg.getBytes(charset).length);
            int mod=16-msg.getBytes(charset).length%16;
            System.out.println("encrypt con mod is:"+mod);
            if(mod!=0){
            	msg=RCh(msg," ",mod);
            	System.out.println("transfer after encrypt con :"+msg);
            	System.out.println("transfer after encrypt length:"+msg.getBytes(charset).length);
            }
            
            //加密并转换成16进制字符串  
			str = asHex(ecipher.doFinal(msg.getBytes(charset)));
        }catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}catch (BadPaddingException e) {  
            e.printStackTrace();  
        } catch (InvalidKeyException e) {  
            e.printStackTrace();  
        } catch (InvalidAlgorithmParameterException e) {  
            e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
            e.printStackTrace();  
        }  
        return str;  
    }  
      
    /** 
     * 解密，对生成的16进制的字符串进行解密 
     * @param value 解密的数据 
     * @return 
     */  
    public static String decrypt(String value) {  
        try {  
            ecipher.init(Cipher.DECRYPT_MODE, key, paramSpec);  
            if(value!=null && !"".equals(value)){
            	return new String(ecipher.doFinal(asBin(value)),"UTF-8").trim();
            }else{
            	return value;
            }
        } catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  catch (BadPaddingException e) {  
            e.printStackTrace();  
        } catch (InvalidKeyException e) {  
            e.printStackTrace();  
        } catch (InvalidAlgorithmParameterException e) {  
            e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
            e.printStackTrace();  
        }  
        return "";  
    }  
  
    /** 
     * 将字节数组转换成16进制字符串 
     * @param buf 
     * @return 
     */  
    private static String asHex(byte buf[]) {  
        StringBuffer strbuf = new StringBuffer(buf.length * 2);  
        int i;  
        for (i = 0; i < buf.length; i++) {  
            if (((int) buf[i] & 0xff) < 0x10)//小于十前面补零  
                strbuf.append("0");  
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));  
        }  
        return strbuf.toString();  
    }  
  
    /** 
     * 将16进制字符串转换成字节数组 
     * @param src 
     * @return 
     */  
    private static byte[] asBin(String src) {  
        if (src.length() < 1)  
            return null;  
        byte[] encrypted = new byte[src.length() / 2];  
        for (int i = 0; i < src.length() / 2; i++) {  
            int high = Integer.parseInt(src.substring(i * 2, i * 2 + 1), 16);//取高位字节  
            int low = Integer.parseInt(src.substring(i * 2 + 1, i * 2 + 2), 16);//取低位字节  
            encrypted[i] = (byte) (high * 16 + low);  
        }  
        return encrypted;  
    }  
    
    public static String LCh(String sourString, String cChar, int cLen) {
    	String tReturn = "";
		for (int i = 0; i < cLen; i++) {
			tReturn += cChar;
		}
		tReturn =  tReturn+sourString;
		return tReturn;
	}
	public static String RCh(String sourString, String cChar, int cLen) {
		String tReturn = "";
		for (int i = 0; i < cLen; i++) {
			tReturn += cChar;
		}
		tReturn = sourString + tReturn;
		return tReturn;
	}
	
	
	public static void main(String[] args) {
		String param = "{\"header\":{\"password\":\"fcb905a7d9c34023e790eb42cbe27d1e\",\"channelId\":\"05135\",\"channelName\":\"华胜集团\"},\"body\":{\"orderInfo\":{\"orderId\":\"16QKIpDU00657196\"}}}";
		System.out.println(encrypt(param));
		String aa = "871e5ffc0eb4252ac2c73f7a3b6d4b6bdcd9f99544cc4545af0f793f5892e9b160e1caae2e8325f028e8707413ae87544ae0d166da10fef4a3c9b4f9d39d0316e5cfd40bc0f913be0a087c3763318503";
		System.out.println(decrypt(aa));
	}
}
